#ifndef PARAMS_H
#define PARAMS_H
#include <vector>
#include <cstdint>
#include <stdexcept>
#include <gmpxx.h>
#include <algorithm>
#include "utils.h"
#include "ring.h"
// 原值为5，与自举对应为3
const uint64_t GaloisGen = 3;
enum RingType {
    Standard,          // Z[X]/(X^N + 1) (Default)
    ConjugateInvariant // Z[X+X^-1]/(X^2N + 1)
};
/* *
 * @class Context
 * @brief 表示同态加密算法中的上下文信息，包含了加密算法所需的各种参数和环。
 *
 * 该类封装了与加密相关的上下文，包括环的相关信息、模数、噪声参数等。它用于在同态加密操作中存储和传递必要的信息。
 */
class Context {
public:
    int logN;
    std::vector<uint64_t> qi;
    std::vector<uint64_t> pi;
    double sigma;
    uint64_t t;
    Ring *ringQ;
    Ring *ringP;
    RingType ringType;
    Ring *ringQMul;
    Ring *ringT;

    Context() {}
    Context(int logN, const std::vector<uint64_t> &qi, const std::vector<uint64_t> &pi, uint64_t t, double sigma,
        RingType ringType = RingType::Standard);
    // 拷贝构造函数
    Context(const Context &other);
    Context &operator = (const Context &other);
    // 移动构造函数
    Context(Context &&other) = delete;
    Context &operator = (Context &&other) = delete;


    int QCount();
    int PCount();
    int MaxLevel();
    int N();
    uint64_t T();
    int Alpha();
    int Beta();
    RingQP *NewRingQP();
    uint64_t GaloisElementForColumnRotationBy(int k);
    uint64_t GaloisElementForRowRotation();
    uint64_t InverseGaloisElement(uint64_t galEl);
    int QiOverflowMargin(int level);
    int PiOverflowMargin(int level);
    std::vector<uint64_t> GaloisElementsForRowInnerSum();
};

#endif // PARAMS_H